import sys
import os
import glob
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtCore import Qt
from PIL import ImageGrab
from pynput import keyboard

class ScreenshotWindow(QWidget):
    def __init__(self):
        super().__init__()
        # 设置全屏无边框窗口，半透明黑色背景
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setWindowState(Qt.WindowFullScreen)
        self.setAttribute(Qt.WA_TranslucentBackground)
        # 更明显的半透明红色背景便于调试
        # 使用实色背景确保可见性
        self.setStyleSheet("background-color: red;")
        print("已设置实色红色背景")
        
        # 显式设置窗口覆盖整个屏幕
        screen_geometry = QApplication.desktop().availableGeometry()
        self.setGeometry(screen_geometry)
        print(f"截图窗口已创建，尺寸: {screen_geometry.width()}x{screen_geometry.height()}")
        
        self.begin = None
        self.end = None
        # 使用更可靠的屏幕尺寸获取方式（排除任务栏区域）
        # 使用QGuiApplication获取主屏幕尺寸
        from PyQt5.QtGui import QGuiApplication
        screen = QGuiApplication.primaryScreen()
        screen_geometry = screen.availableGeometry()
        print(f"主屏幕尺寸: {screen_geometry.width()}x{screen_geometry.height()}, 屏幕名称: {screen.name()}")
        # 启用样式表背景支持
        self.setAttribute(Qt.WA_StyledBackground, True)
        # 最简化窗口创建
        print("创建基础截图窗口...")
        # 恢复背景渲染支持
        self.setAutoFillBackground(True)
        self.setAttribute(Qt.WA_StyledBackground, True)
        # 仅保留必要标志
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.Window)
        # 移除边框以确保全屏
        self.setWindowState(Qt.WindowFullScreen)
        # 高对比度样式
        self.setStyleSheet("background-color: red; border: 10px solid yellow;")
        # 基础显示
        self.show()
        # 强制事件处理
        QApplication.processEvents()
        # 最终调试信息
        print(f"简化窗口状态: 可见={self.isVisible()}, 全屏={self.isFullScreen()}, 样式={self.styleSheet()}")

    def paintEvent(self, event):
        super().paintEvent(event)
        if self.begin and self.end:
            painter = QPainter(self)
            painter.setPen(QPen(Qt.red, 2, Qt.SolidLine))
            # 绘制选择矩形
            rect = Qt.QRect(self.begin, self.end)
            painter.drawRect(rect)
            # 填充选区内半透明白色
            painter.fillRect(rect, Qt.QBrush(Qt.QColor(255, 255, 255, 50)))

    def mousePressEvent(self, event):
        self.begin = event.pos()
        self.end = self.begin
        self.update()

    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()

    def keyPressEvent(self, event):
        # 监听Alt+X组合键
        if event.modifiers() == Qt.AltModifier and event.key() == Qt.Key_X:
            self.save_screenshot()

    def save_screenshot(self):
        if not (self.begin and self.end):
            self.close()
            return

        # 获取选择区域坐标
        x1 = min(self.begin.x(), self.end.x())
        y1 = min(self.begin.y(), self.end.y())
        x2 = max(self.begin.x(), self.end.x())
        y2 = max(self.begin.y(), self.end.y())

        # 隐藏窗口避免截取半透明覆盖层
        self.hide()
        QApplication.processEvents()  # 确保窗口隐藏

        # 截取屏幕区域
        try:
            screenshot = ImageGrab.grab(bbox=(x1, y1, x2, y2))
        except Exception as e:
            print(f"截图失败: {e}")
            self.close()
            return

        # 确保保存目录存在
        save_dir = r"D:\img"
        os.makedirs(save_dir, exist_ok=True)

        # 生成递增文件名
        file_pattern = os.path.join(save_dir, "*.png")
        existing_files = glob.glob(file_pattern)
        file_numbers = []

        for file in existing_files:
            try:
                # 提取文件名中的数字部分
                filename = os.path.basename(file)
                num = int(os.path.splitext(filename)[0])
                file_numbers.append(num)
            except (ValueError, IndexError):
                continue

        next_num = max(file_numbers) + 1 if file_numbers else 1
        new_filename = f"{next_num:02d}.png"
        save_path = os.path.join(save_dir, new_filename)

        # 保存截图
        try:
            screenshot.save(save_path, "PNG")
            print(f"截图已保存: {save_path}")
        except Exception as e:
            print(f"保存失败: {e}")

        self.close()

from PyQt5.QtCore import pyqtSignal, QObject

class ScreenshotSignal(QObject):
    trigger_screenshot = pyqtSignal()

class ScreenshotTool:
    def __init__(self):
        # 创建信号对象用于主线程通信
        self.signal = ScreenshotSignal()
        self.signal.trigger_screenshot.connect(self.start_screenshot)
        
        # 注册F9热键
        self.hotkey_listener = keyboard.GlobalHotKeys({
            '<f9>': lambda: self.signal.trigger_screenshot.emit()
        })
        self.app = None

    def start_screenshot(self):
        """启动截图界面"""
        print("F9热键已触发，正在启动截图界面...")
        # 确保只创建一个QApplication实例
        self.app = QApplication.instance()
        if self.app is None:
            self.app = QApplication(sys.argv)
        # 检查是否已存在窗口实例
        if hasattr(self, 'window') and self.window and self.window.isVisible():
            # 如果窗口已存在且可见，将其激活并置顶
            self.window.raise_()
            self.window.activateWindow()
            print("已存在窗口实例，已激活现有窗口")
            return

        # 创建新窗口实例
        self.window = ScreenshotWindow()
        self.window.raise_()
        self.window.activateWindow()
        print(f"窗口显示状态: {self.window.isVisible()}, 尺寸: {self.window.geometry().width()}x{self.window.geometry().height()}")
        # 已在主线程启动事件循环，无需重复调用
        # self.app.exec_()

    def run(self):
        """在主线程运行应用程序"""
        import threading
        print(f"主线程ID: {threading.get_ident()}")
        
        # 在主线程创建QApplication
        self.app = QApplication(sys.argv)
        print("QApplication已在主线程初始化")
        
        # 在后台线程启动热键监听
        def start_listener():
            try:
                with self.hotkey_listener:
                    print(f"热键监听线程ID: {threading.get_ident()}")
                    print("F9热键已注册，等待触发...")
                    self.hotkey_listener.join()
            except Exception as e:
                print(f"热键监听错误: {e}")
        
        listener_thread = threading.Thread(target=start_listener, daemon=True)
        listener_thread.start()
        
        # 运行应用程序事件循环
        print("启动QApplication事件循环...")
        self.app.exec_()

if __name__ == "__main__":
    # 确保中文正常显示
    app = QApplication(sys.argv)
    tool = ScreenshotTool()
    tool.start_screenshot()
    app.exec_()
    print("应用事件循环已启动")

# 依赖安装说明：
# pip install PyQt5 pynput pillow